#include <functional>
#include <iostream>
#include <thread>
#include <boost/asio.hpp>

// printer类用于管理两个异步定时器
class printer
{
public:
    // 构造函数：初始化strand和两个定时器
    printer(boost::asio::io_context &io)
        : strand_(boost::asio::make_strand(io)),        // 创建strand确保回调的串行执行
          timer1_(io, boost::asio::chrono::seconds(1)), // 第一个定时器，初始间隔1秒
          timer2_(io, boost::asio::chrono::seconds(1)), // 第二个定时器，初始间隔1秒
          count_(0)                                     // 初始化计数器
    {
        // 注册进去使用了strand_ 保证是顺序的
        //  启动第一个定时器的异步等待
        timer1_.async_wait(boost::asio::bind_executor(strand_,
                                                      std::bind(&printer::print1, this)));

        // 启动第二个定时器的异步等待
        timer2_.async_wait(boost::asio::bind_executor(strand_,
                                                      std::bind(&printer::print2, this)));
    }

    // 析构函数：打印最终计数
    ~printer()
    {
        std::cout << "Final count is " << count_ << std::endl;
    }

    // 第一个定时器的回调函数
    void print1()
    {
        if (count_ < 10) // 限制执行次数
        {
            // 打印线程ID
            std::cout << "Thread ID: " << std::this_thread::get_id() << std::endl;

            std::cout << "Timer 1: " << count_ << std::endl;
            ++count_;

            // 设置下一次触发时间（当前时间+1秒）
            timer1_.expires_at(timer1_.expiry() + boost::asio::chrono::seconds(1));

            // 再次启动异步等待
            timer1_.async_wait(boost::asio::bind_executor(strand_,
                                                          std::bind(&printer::print1, this)));
        }
    }

    // 第二个定时器的回调函数
    void print2()
    {
        if (count_ < 10) // 限制执行次数
        {
            std::cout << "Thread ID: " << std::this_thread::get_id() << std::endl;

            std::cout << "Timer 2: " << count_ << std::endl;
            ++count_;

            // 设置下一次触发时间（当前时间+1秒）
            timer2_.expires_at(timer2_.expiry() + boost::asio::chrono::seconds(1));

            // 再次启动异步等待
            timer2_.async_wait(boost::asio::bind_executor(strand_,
                                                          std::bind(&printer::print2, this)));
        }
    }

private:
    // strand用于确保回调函数的串行执行，避免多线程并发访问
    boost::asio::strand<boost::asio::io_context::executor_type> strand_;
    boost::asio::steady_timer timer1_; // 第一个定时器
    boost::asio::steady_timer timer2_; // 第二个定时器
    int count_;                        // 共享计数器
};

int main()
{
    boost::asio::io_context io; // 创建IO上下文
    printer p(io);              // 创建printer对象

    // 创建新线程运行io_context
    std::thread t([&]
                  { io.run(); });

    // 在主线程中也运行io_context
    io.run();

    // 等待线程结束
    t.join();

    return 0;
}